package com.liangtian.mdm.dm.config.service.impl;

import com.liangtian.mdm.base.dao.JdbcDao;
import org.apache.commons.lang3.StringUtils;
import com.liangtian.mdm.dm.config.dao.AttrConfigDao;
import com.liangtian.mdm.dm.config.model.AttrConfig;
import com.liangtian.mdm.dm.config.service.AttrConfigService;
import com.liangtian.mdm.dm.listener.CacheUtil;
import com.liangtian.mdm.dm.listener.Ehcache;
import com.liangtian.mdm.dm.model.dao.ModelDao;
import com.liangtian.mdm.dm.model.model.Model;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.ehcache.Cache;
import org.ehcache.Cache.Entry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class AttrConfigServiceImpl implements AttrConfigService {

    @Autowired
    private AttrConfigDao attrConfigDao;

    @Autowired
    private JdbcDao jdbcDao;

    @Autowired
    private ModelDao modelDao;

    @Autowired
    private CacheUtil cacheUtil;

    @SuppressWarnings({"rawtypes", "unchecked"})
    @Override
    public PageInfo queryAttributesList(Map<String, Object> param) {
        PageInfo<List<Model>> pageInfo = null;
        try {
            Object pNo = param.get("pageNum");
            int pageNum, pageSize;
            // export
            if (pNo != null && !"NaN".equals(pNo)) {
                pageNum = Integer.parseInt(pNo.toString());// 页码
            } else {
                pageNum = 1;
            }
            // pageSize=0时不分页
            pageSize = Integer.parseInt(param.get("limit").toString());// 模型定义页面要显示数据条数
            PageHelper.startPage(pageNum, pageSize);// 开始分页标志（当前页，显示条数）

            List<AttrConfig> attrConfigList = attrConfigDao.queryAllAttributes(param);
            pageInfo = new PageInfo(attrConfigList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pageInfo;
    }

    @Override
    public void updateAttrConfig(AttrConfig attrConfig) {
        // 如果设置字段为不显示，则设置配置为初始化字段
        if (0 == attrConfig.getIsShow()) {
            //attrConfig.setShowLength(0);
            attrConfig.setShowLength(20);
            attrConfig.setShowOrder(110);
            attrConfig.setShowPage("0");
            attrConfig.setIsNull(1);
            attrConfig.setIsOrder(0);
            attrConfig.setOrderRule(0);
        }
        // 设置字段显示，但是不排序，则不需要排序规则,初始化为标识字段
        if (1 == attrConfig.getIsShow() && 0 == attrConfig.getIsOrder()) {
            attrConfig.setOrderRule(0);
        }
        if ("VARCHAR2".equals(attrConfig.getAttrType())) {
            if (!"4".equals(attrConfig.getModuleType())) {//非编码
                if ("6".equals(attrConfig.getModuleType())) {
                    attrConfig.setModuleType(attrConfig.getModuleType());
                } else {
                    attrConfig.setModuleType("");
                }
                attrConfig.setCodeRule("");
                attrConfig.setWaterCodeLength("");
            } else {//输入框，且是编码
                if (attrConfig.getSetCodeTime() == 1) {//如果是数据录入的话
                    attrConfig.setIsNull(0);
                } else {//否则，是审核完成
                    attrConfig.setIsNull(1);
                }
                attrConfig.setDataSourceTable("");
                attrConfig.setDataSourceColumn("");
                attrConfig.setDataSourceShowColumn("");
                attrConfig.setCascadedAttr("");
                attrConfig.setCascadedForeignKey("");
                attrConfig.setSelectedConfigAttr("");
            }
            attrConfig.setIsDefaultParentType(0);
            attrConfig.setViewName("");
            attrConfig.setTabNoName("");//外部选择数据来源
            attrConfig.setIsParentType(0);//是否上下级关系设置为否
        } else {
            if ("radioType".equals(attrConfig.getAttrType()) || "checkBoxType".equals(attrConfig.getAttrType())
                    || "selectList".equals(attrConfig.getAttrType())
                    || "popList".equals(attrConfig.getAttrType())) {
                if ("3".equals(attrConfig.getModuleType())) {
                    attrConfig.setCascadedAttr("");
                    attrConfig.setCascadedForeignKey("");
                    attrConfig.setTabNoName("");//外部选择数据来源
                } else if ("2".equals(attrConfig.getModuleType())) {
                    attrConfig.setSelectedConfigAttr("");
                    attrConfig.setTabNoName("");//外部选择数据来源
                } else if ("1".equals(attrConfig.getModuleType())) {
                    attrConfig.setCascadedAttr("");
                    attrConfig.setCascadedForeignKey("");
                    attrConfig.setSelectedConfigAttr("");
                    attrConfig.setTabNoName("");//外部选择数据来源
                } else if ("5".equals(attrConfig.getModuleType())) {//外部选择数据来源表 - 表名
                    attrConfig.setCascadedAttr("");
                    attrConfig.setCascadedForeignKey("");
                    attrConfig.setSelectedConfigAttr("");
                    attrConfig.setTabNoName(attrConfig.getTabNoName());//外部选择数据来源
                }
                attrConfig.setIsDefaultParentType(0);
                attrConfig.setIsParentType(0);//是否上下级关系设置为否
                attrConfig.setViewName("");
            } else if (attrConfig.getAttrType() != null && ("NUMBER".equals(attrConfig.getAttrType()) || "CLOB".equals(attrConfig.getAttrType())
                    || "BLOB".equals(attrConfig.getAttrType()) || "DATE".equals(attrConfig.getAttrType())
                    || "mailType".equals(attrConfig.getAttrType()) || "hideType".equals(attrConfig.getAttrType()))) {
                attrConfig.setDataSourceTable("");
                attrConfig.setDataSourceColumn("");
                attrConfig.setDataSourceShowColumn("");
                attrConfig.setModuleType("");
                attrConfig.setCodeRule("");
                attrConfig.setWaterCodeLength("");
                attrConfig.setCascadedAttr("");
                attrConfig.setCascadedForeignKey("");
                attrConfig.setSelectedConfigAttr("");
                attrConfig.setIsDefaultParentType(0);
                attrConfig.setViewName("");
                attrConfig.setTabNoName("");//外部选择数据来源
                attrConfig.setIsParentType(0);//是否上下级关系设置为否
            } else if ("listTree".equals(attrConfig.getAttrType())) {
                Model model = cacheUtil.getModel(attrConfig.getModelId());// 获取具体的model
                if ("1".equals(model.getClassType())) {//父子树
                    attrConfig.setClassColumn("0");
                    attrConfig.setTreeViewColumn("");
                } else if ("2".equals(model.getClassType())) {//分类树
                    attrConfig.setIsParentType(0);
                    attrConfig.setIsDefaultParentType(0);
                    attrConfig.setViewName("");
                    attrConfig.setTreeViewColumn(attrConfig.getTreeViewColumn());
                } else {//列表
                    attrConfig.setClassColumn("0");
                    attrConfig.setIsParentType(0);
                    attrConfig.setIsDefaultParentType(0);
                    attrConfig.setViewName("");
                    attrConfig.setTreeViewColumn(attrConfig.getTreeViewColumn());
                }
                attrConfig.setTabNoName("");//外部选择数据来源
                attrConfig.setModuleType("");
                attrConfig.setCodeRule("");
                attrConfig.setWaterCodeLength("");
                attrConfig.setCascadedAttr("");
                attrConfig.setCascadedForeignKey("");
                attrConfig.setSelectedConfigAttr("");
            }
        }
        attrConfigDao.updateAttrConfig(attrConfig);

        /**
         * 2016-09-06 張濤 更新缓存
         */
        String modelId = attrConfig.getModelId();
        if (!StringUtils.isBlank(modelId)) {
            Map<String, String> cond = new HashMap<>();
            cond.put("modelId", modelId);
            cond.put("attrId", attrConfig.getAttrId());
            List<AttrConfig> acList = attrConfigDao.queryValidAttributeList(cond);
            if (acList != null && !acList.isEmpty()) {
                AttrConfig ac = acList.get(0);
                HashMap<String, AttrConfig> am = cacheUtil.getAttrMap(modelId);
                // org.springframework.beans.BeanUtils.copyProperties(attrConfig, am);
                // 更新当前属性显示设置
                am.put(ac.getAttrColumn(), ac);
                // 若cache使用offheap，則必須深度更新！！！
            }
        }
        // attrConfig.classColumn值为1属于分类树的关联列，model.classColumn为实际列名
        if ("1".equals(attrConfig.getClassColumn())) {
            Model model = cacheUtil.getModel(modelId);// 获取具体的model
            model.setClassColumn(attrConfig.getAttrColumn());// 将属性列保存到model模型里面
            modelDao.updateModel(model);
        }
        // 属性设置的改变  可能影响列的实际关联关系
        cacheUtil.removeElement(modelId);//清除属性列表缓存
        cacheUtil.removeAttrConfig(modelId);//清除属性设置缓存缓存
//		   cacheUtil.removeQueryCols(modelId);//清除查询列缓存缓存
//		   cacheUtil.removeAttrConfig(modelId);//添加了属性设置缓存清除功能
    }

    @Override
    public AttrConfig queryAttrConfig(String model_id, String attr_id) {
        return cacheUtil.getAttrConfig(model_id, attr_id);
    }

    @Override
    public List<Model> queryAllModelTables(String classType, String model_id) {

        List<Model> lm = new ArrayList<Model>();
        if (model_id != null && !"".equals(model_id)) {
            Model m = cacheUtil.getModel(model_id);
            if (classType != null && classType.equals(m.getClassType()))
                lm.add(m);
        } else {
            Cache<String, Model> cache = Ehcache.getCache().getModelCache();
            Iterator<Entry<String, Model>> it = cache.iterator();
            while (it.hasNext()) {
                Model m = it.next().getValue();
                if (classType != null && !"".equals(classType)) {
                    if (classType.equals(m.getClassType()))
                        lm.add(m);
                } else
                    lm.add(m);
            }
        }
        return lm;
    }


    @Override
    public List<AttrConfig> queryModelTable4Column(String model_id) {
        return cacheUtil.getAttrList(model_id);
    }

    @Override
    public List<AttrConfig> queryCascadeAttr(String model_id) {

        List<AttrConfig> acList = new ArrayList<>();
        HashMap<String, AttrConfig> ma = cacheUtil.getAttrMap(model_id);
        for (AttrConfig ac : ma.values()) {
            //只显示---单选，下拉框，弹出框
            if ("radioType".equals(ac.getAttrType())
                    || "selectList".equals(ac.getAttrType())
                    || "popList".equals(ac.getAttrType())) {
                acList.add(ac);
            }
        }
        return acList;
    }

    @Override
    public List<Map> querySelectedAttr(String sql) {
        try {
//			return jdbcDao.queryObjectList(sql);
            return attrConfigDao.queryBySql(sql);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<AttrConfig> queryAttr(String model_id) {
        return cacheUtil.getAttrList(model_id);
    }

    @Override
    public Model queryModelType(String model_id) {
        return cacheUtil.getModel(model_id);
    }

    @Override
    /**
     * <p>TODO:父子树属性设置默认父子关系是否设置</p>
     * @author : xiaoliu
     * @date :2017年4月26日上午9:26:44
     */
    public List<AttrConfig> queryAttributesListIsParent(Map<String, String> map) {
        List<AttrConfig> list = new ArrayList<>();
        String modelId = map.get("modelId");
        String isP = map.get("isP");
        Map<String, AttrConfig> attrMap = cacheUtil.getAttrMap(modelId);
        for (String column : attrMap.keySet()) {
            AttrConfig ac = attrMap.get(column);
            if (isP.equals(String.valueOf(ac.getIsDefaultParentType()))) {
                list.add(ac);
            }
        }
        return list;
    }

    @Override
    public List<AttrConfig> initHyCodeValues(Map<String, Object> param) {
        //List<HyCodeShow> hcsLst = new ArrayList<HyCodeShow>();
        List<AttrConfig> acLst = attrConfigDao.queryValidAttributeList(param);
		/*for (int i = 0; i < dsLst.size(); i++) {
			Map<String,Object> dsMap=dsLst.get(i);
			String ds_table = (String) dsMap.get("dataSourceTable");
			String dss_column = (String) dsMap.get("dataSourceShowColumn");
			Map<String,Object> cond = new HashMap<>();
			cond.put("columns", "id," + dss_column);
			cond.put("tableName", TableConst.TABLEPREFIX + ds_table);
			cond.put("orderBy", "id");
			List<Map<String,Object>> dataLst = jspActionDao.queryList(cond);
			for (int j = 0; j < dataLst.size(); j++) {
				Map<String, Object> dataMap=dataLst.get(j);
				HyCodeShow hcs = new HyCodeShow();
				hcs.setField((String)dsMap.get("attrName"));
				hcs.setValue((String)dataMap.get(dss_column.toLowerCase()));
				hcs.setId(ds_table +"@@"+ (String)dataMap.get("id"));
				hcsLst.add(hcs);
			}
		}*/
        return acLst;
    }


    @Override
    public List<AttrConfig> queryCodeAttrs(Map<String, Object> param) {
        return attrConfigDao.queryAttributesListPermision(param);
    }

    /**
     * <p>TODO  动态模型选择设置弹出列表，添加一个组件，外部数据来源，专门处理用于跟非动态模型数据结合的方法</p>
     * 此方法，用来校验用户输入的外部引用的表名是否正确
     *
     * @param : @param tableName
     * @param : @return （1.正确 返回 true   2.不正确  返回 false）
     * @author : xiaoliu
     * @date :2017年8月1日下午4:08:10
     */

    @Override
    public boolean checkTabNoNameValide(String tableName) {
        tableName = tableName.toUpperCase();
        boolean flag = jdbcDao.executeSysSql(tableName);
        return flag;

    }

    /**
     * <p>TODO  当用户输入的表名是正确的话，查询该表中所有的属性列集合</p>
     *
     * @param : @param tableName
     * @param : @return map
     * @author : xiaoliu
     * @date :2017年8月1日下午4:23:19
     */

    @Override
    public List<AttrConfig> queryTabNoNameColumns(String tableName) {
        tableName = tableName.toUpperCase();
        List<AttrConfig> acList = attrConfigDao.querySysTableForComments(tableName);
        return acList;
    }

}
